package com.jiashihui.schema_lgorithm.schema.proxy;

/**
 * @author jiashihui
 * @代理模式: 多一个代理类出来，替原对象进行一些操作
 * @date 2019/03/14
 * <p>
 * 代理模式的好处:可以将功能划分的更加清晰，有助于后期维护。
 * <p>
 * 三种代理模式：静态代理、动态代理（也叫JDK代理）、Cglib代理
 * 静态代理和JDK代理有一个共同的缺点，就是目标对象必须实现一个或多个接口，如果没有实现接口，则使用Cglib代理
 * 在Spring的AOP编程中：如果加入容器的目标对象有实现接口，用JDK代理；如果目标对象没有实现接口，用Cglib代理
 *
 * JDK动态代理:
 * 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类，在调用具体方法前调用InvokeHandler来处理。
 * CGLiB动态代理:
 * 利用ASM开源包，对代理对象类的class文件加载进来，通过修改其字节码生成子类来处理。
 *
 * JDK动态代理和CGLIB字节码生成的区别？
 * 1、JDK动态代理只能对实现了接口的类生成代理，而不能针对类。
 * 2、CGLIB是针对类实现代理，主要是对指定的类生成一个子类，覆盖其中的方法，并覆盖其中方法实现增强，但是因为采用的是继承，所以该类或方法最好不要声明成final，对于final类或类方法，是无法继承的。
 */
public class HZFangProxyTest {
    public static void main(String[] args) {

        //静态代理
        Rent target = new RenterImpl();
        Rent renter = new HZFangProxyImpl(target);
        renter.rentHouse();

        System.out.println("#############################分割线##############################");

        // 动态代理（JDK）
        Rent target2 = new RenterImpl();
        Rent proxy = new JDKProxy().bind(target2);
        proxy.rentHouse();

        System.out.println("#############################分割线##############################");

        // Cglib代理
        RenterImpl target3 = new RenterImpl();
        RenterImpl proxy2 = (RenterImpl) new ProxyFactory(target3).getProxyInstance();
        proxy2.rentHouse();
    }
}
